/*
 * GuiHelper.java
 *
 */

package pl.edu.pw.mini.gui;

import java.awt.Desktop;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.ListSelectionModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeSelectionModel;
import pl.edu.pw.mini.DirtyLogHelper;
import pl.edu.pw.mini.adapter.GoogleStrategy;
import pl.edu.pw.mini.adapter.IAdapterStrategy;
import pl.edu.pw.mini.adapter.IConnectionState;
import pl.edu.pw.mini.adapter.ZohoStrategy;
import pl.edu.pw.mini.adapter.documents.Document;
import pl.edu.pw.mini.exceptions.AuthenticationException;
import pl.edu.pw.mini.exceptions.ConnectionException;
import pl.edu.pw.mini.exceptions.InternalRuntimeException;

/**
 *
 * @author cdendek
 */
public class GuiHelper {
    
    /** Creates a new instance of GuiHelper */
    private GuiHelper() {
    }
    public static Map<MutableTreeNode, Document> fillTree(javax.swing.JTree tree, List<Document> wbList){
        Map<MutableTreeNode,Document> workbookIndex = new HashMap<MutableTreeNode,Document>();
        // Find node to which new node is to be added
        int startRow = 0;
        String prefix = "";
        MutableTreeNode root=new DefaultMutableTreeNode("Docs") ;
        for (Document wb:wbList){
            MutableTreeNode newNode = new DefaultMutableTreeNode(wb.getTitle(),false);
            workbookIndex.put(newNode,wb);
            root.insert(newNode,root.getChildCount());
        }
        DefaultTreeModel model=new DefaultTreeModel(root);
        tree.setModel(model);
        return workbookIndex;
    }
    
    public static Map<MutableTreeNode, Object> fillTree(javax.swing.JTree tree,Map<String,Object> treeMap){
        MutableTreeNode root=new DefaultMutableTreeNode("Docs") ;
        Map<MutableTreeNode,Object> workbookIndex =fillTree(root, treeMap);
        Collection<Object>col =workbookIndex.values();
        Set allDocsSet=new HashSet();
        for(Object obj:col){
            if (obj instanceof List){
                allDocsSet.addAll((List)obj);
            }
        }
        workbookIndex.put(root,new ArrayList(allDocsSet));
        DefaultTreeModel model=new DefaultTreeModel(root);
        tree.setModel(model);
        return workbookIndex;
    }
    
    public static Map<MutableTreeNode, Object> fillTree(MutableTreeNode root, Map<String,Object> treeMap){
        Map<MutableTreeNode,Object> workbookIndex = new HashMap<MutableTreeNode,Object>();
        // Find node to which new node is to be added
        int startRow = 0;
        String prefix = "";
        Set<String> sst=treeMap.keySet();
        for (String key:sst){
            MutableTreeNode newRoot=new DefaultMutableTreeNode(key);
            root.insert(newRoot,root.getChildCount());
            Object o=treeMap.get(key);
            if (o instanceof Map){
                workbookIndex.putAll(fillTree(newRoot, (Map<String,Object>)o));
            } else{
                //It's instance of List<Document>
                //MutableTreeNode newNewRoot=new DefaultMutableTreeNode(o.toString());
                //newRoot.insert(newNewRoot,0);
                //workbookIndex.put(newNewRoot,o);
                workbookIndex.put(newRoot,o);
            }
        }
        return workbookIndex;
    }
    
    
    static void exceptionHandler(ConnectionException ex, String service) {
        DirtyLogHelper.append(ex);
        showMessage("Can't reach "+service+" service.\n"+ex.getMessage(),service,javax.swing.JOptionPane.ERROR_MESSAGE);
    }
    
    static void exceptionHandler(AuthenticationException ex, String service) {
        DirtyLogHelper.append(ex);
        showMessage("Provided account and password do not match.\n"+ex.getMessage(),service,javax.swing.JOptionPane.ERROR_MESSAGE);
    }
    static void exceptionHandler(InternalRuntimeException ex, String service) {
        DirtyLogHelper.append(ex);
        showMessage(ex.getMessage(),service,javax.swing.JOptionPane.ERROR_MESSAGE);
    }
    static void exceptionHandler(Exception ex, String service) {
        DirtyLogHelper.append(ex);
        ByteArrayOutputStream bos=new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(bos);
        ex.printStackTrace(ps);
        ps.flush();
        String excStr=""
                //"\n"+ex.toString()+"\n"+bos.toString()
                ;
        showMessage("Unexpected error has just occured during access to "+service+" service.\n"+ex.getMessage(),service,javax.swing.JOptionPane.ERROR_MESSAGE);
    }
    
    static boolean checkAdapterCredWithWarning(IAdapterStrategy strategy){
        IConnectionState ics=strategy.getConnectionState();
        if (ics==null || ics.isPasswordEmpty()){
            showMessage("User not authenticated.",strategy.getServiceId(),javax.swing.JOptionPane.WARNING_MESSAGE);
            return false;
        }
        return true;
    }
    
    static boolean checkZohoCredWithWarning(){
        return checkAdapterCredWithWarning(ZohoStrategy.getInstance());
    }
    static boolean checkGoogleCredWithWarning(){
        return checkAdapterCredWithWarning(GoogleStrategy.getInstance());
    }
    
    static void prepareMainDocumentFrame(JTable documentTable,JTree documentCategoriesTree){
        DefaultTreeSelectionModel dtsm=new DefaultTreeSelectionModel();
        dtsm.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        documentCategoriesTree.setSelectionModel(dtsm);
        
        documentTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        documentTable.setAutoCreateRowSorter(true);
    }
    static void showMessage(String message,String service,int type){
        javax.swing.JOptionPane.showMessageDialog(null,message, service,type);
    }
    static void openURLInDefaultBrowser(URI navigateTo){
        if (!Desktop.isDesktopSupported()){
            DirtyLogHelper.append("Default browser is not supported. Not navigating to "+navigateTo+".");
        }
        try {
            Desktop.getDesktop().browse(navigateTo);
        } catch (IOException ex) {
            DirtyLogHelper.append(ex);
        }
    }

    static void openURLInDefaultBrowser(String string) {
        try {
            openURLInDefaultBrowser(new URI(string));
        } catch (URISyntaxException ex) {
            DirtyLogHelper.append(ex);
        }
    }
}
